package org.thingsboard.server.controller;


import com.alibaba.fastjson.JSONObject;
import com.jcraft.jsch.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.TenantIp;
import org.thingsboard.server.dao.flv.FLVService;
import org.thingsboard.server.dao.model.sql.TenantIpEntity;
import org.thingsboard.server.dao.tenantIp.TenantIpService;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.transport.mqtt.util.NfsUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.time.LocalDate;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Vector;


@RestController
@TbCoreComponent
@RequestMapping("/api/flv")
@Slf4j
public class FLVController {
    @Autowired
    private FLVService flvService;

    @Autowired
    private TenantIpService tenantIpService;

    /**
     * 根据url获取摄像头实时视频信息
     *
     * @param response
     * @param request
     * @param url
     */

    @GetMapping("/get_flv")
    public void getFlvByRtsp(HttpServletResponse response,
                             HttpServletRequest request, @RequestParam("url") String url) {
        log.info("请求摄像头rtsp地址------>{}", url);
        if (StringUtils.isEmpty(url)) {
            throw new RuntimeException("rtsp地址不能为空");
        }
        flvService.getFlvByRtsp(url, response, request);
    }

    @GetMapping("/get_img")
    public JSONObject getCamerasImg(@RequestParam("info") String info, @RequestParam("deviceName") String deviceName) {
        log.info("查看截图的信息------>{},{}", info, deviceName);
        JSONObject result = new JSONObject();
        //127.0.0.1:/data0/media/thingsboard:/20231108/bfea27369fc046b69a14356fff916f10.jpg
        if (StringUtils.isEmpty(info) || StringUtils.isEmpty(deviceName)) {
            //如果没有则返回默认图片
            throw new RuntimeException("请求参数为空!");
        }
        String[] infos = info.split(":");
        byte[] imageByte = NfsUtil.download(infos[0], infos[1], infos[2]);
        //报警截图
        result.put("img1", Base64.getEncoder().encodeToString(imageByte));
        //原正常图片   命名规则   设备名.jpg
        //根据设备名称查询ip
        String ip = tenantIpService.getIpByDeviceName(deviceName);
        byte[] img2 = NfsUtil.download(ip, "/data0/media", "/thingsboard/default/" + deviceName + ".jpg");
        result.put("img2", Base64.getEncoder().encodeToString(img2));
        return result;
    }

    @PostMapping("/http_url")
    public JSONObject getCameraImgByHttpUrl(@RequestBody JSONObject jsonObject) {
        JSONObject params = jsonObject.getJSONObject("params");
        String url = String.valueOf(params.get("url"));
        String deviceName = String.valueOf(params.get("deviceName"));
        log.info("查看截图的信息------>{},{}", url, deviceName);
        //String http_url = "http://" + ip + ":30000/media" + path + "/" + fileName;
        JSONObject result = new JSONObject();
        if (StringUtils.isEmpty(url)) {
            result.put("img", "请求参数为空！");
            return result;
        }
        String nfsDir = "/data0/media";
        int startIndex = url.indexOf("//");
        int endIndex = url.lastIndexOf(":");
        String ip = url.substring(startIndex + 2, endIndex);
        String[] split = url.split("media");
        byte[] imageByte = new byte[0];
        try {
            imageByte = NfsUtil.download(ip, nfsDir, split[1]);
        } catch (Exception e) {
            log.warn("{}该图片不存在！", url);
            ClassPathResource resource = new ClassPathResource("images/default.jpg");
            try {
                imageByte = FileCopyUtils.copyToByteArray(resource.getInputStream());
            } catch (IOException ex) {
                throw new RuntimeException("获取默认图片失败");
            }
        }
        result.put("img1", Base64.getEncoder().encodeToString(imageByte));
        //原正常图片   命名规则   设备名.jpg
        String ip1 = tenantIpService.getIpByDeviceName(deviceName);
        byte[] img2 = new byte[0];
        try {
            img2 = NfsUtil.download(ip1, "/data0/media", "/thingsboard/default/" + deviceName + ".jpg");
        } catch (Exception e) {
            log.warn("{}该图片不存在！", deviceName);
            ClassPathResource resource = new ClassPathResource("images/default.jpg");
            try {
                img2 = FileCopyUtils.copyToByteArray(resource.getInputStream());
            } catch (IOException ex) {
                throw new RuntimeException("获取默认图片失败");
            }
        }
        result.put("img2", Base64.getEncoder().encodeToString(img2));
        return result;

    }

    //定期删除旧的报警图片
//    @Scheduled(cron = "")
    @PostMapping("/deleteOldImg")
    public void deleteOldImg() {
        //获取所有ip循环连接删除
        List<TenantIp> ipList = tenantIpService.getIpAndPwd();
        ipList.forEach(
                ipl -> {
                    //执行删除操作
                    String user = "root";
                    String password = ipl.getIp();//存加密密码
                    String host = ipl.getIp();
                    int port = 22;
                    //获取要删除文件夹    获取前两个月的年月
                    LocalDate currentDate = LocalDate.now();
                    LocalDate previousDate = currentDate.minusMonths(2);
                    int year = previousDate.getYear();
                    int month = previousDate.getMonthValue();
                    String filePath = "/data0/media/thingsboard/" + year + "/" + month;
                    ChannelSftp sftp = null;
                    Session session = null;
                    try {
                        JSch jsch = new JSch();
                        session = jsch.getSession(user, host, port);
                        session.setPassword(password);
                        session.setConfig("StrictHostKeyChecking", "no");
                        session.connect();
                        Channel channel = session.openChannel("sftp");
                        channel.connect();
                        sftp = (ChannelSftp) channel;
                        deleteFiles(sftp, filePath);
                        sftp.rmdir(filePath);
                    } catch (JSchException e) {
                        e.printStackTrace();
                    } catch (SftpException e) {
                        e.printStackTrace();
                    } finally {
                        if (sftp != null && sftp.isConnected()) {
                            sftp.disconnect();
                        }
                        if (session != null && session.isConnected()) {
                            session.disconnect();
                        }
                    }
                }
        );
    }

    private static void deleteFiles(ChannelSftp sftp, String folderPath) throws SftpException {
        Vector<ChannelSftp.LsEntry> entries = sftp.ls(folderPath);
        for (ChannelSftp.LsEntry entry : entries) {
            String fileName = entry.getFilename();
            if (!fileName.equals(".") && !fileName.equals("..")) {
                String filePath = folderPath + "/" + fileName;
                if (entry.getAttrs().isDir()) {
                    deleteFiles(sftp, filePath);  // 递归调用删除子文件夹内的文件
                    sftp.rmdir(filePath);  // 删除空文件夹
                } else {
                    sftp.rm(filePath);  // 删除文件
                }
            }
        }
    }

    //更新正常图片
    @PostMapping("/updateImgByList")
    public void updateDeviceImg(@RequestBody List<String> deviceNameList) {
        if (deviceNameList != null && deviceNameList.size() > 0) {
            deviceNameList.forEach(device -> {
                //获取处理中心的ip
                Map camerasAndId = tenantIpService.getCamerasIdByDeviceName(device);
                String ip = String.valueOf(camerasAndId.get("ip"));
                String cameraId = String.valueOf(camerasAndId.get("cameraid"));
                log.info("查询场地ip请求参数------->{},返回结果------->{}-----{}", device, ip, cameraId);
                //请求获取图片信息
                try {
                    if (!(StringUtils.isEmpty(ip) || StringUtils.isEmpty(cameraId))) {
                        String url = "http://" + ip + ":30005/cameraStream/getManualCapture?cameraId=" + cameraId;
                        byte[] imgBytes = NfsUtil.getRequest(url);
//                        byte[] imgBytes = fileToBytes("E:\\bizhi\\4b2aa7bf90824d1c906a57a0bf4240a7.png");
                        String path = "/thingsboard/default";
                        // 使用 UUID 随机生成文件名
                        String fileName = device + ".jpg";
                        String nfsDir = "/data0/media";
                        boolean upload = false;
                        try {
                            log.info("ip----->{},nfsDir----->{},path------>{},fileName---->{}", ip, nfsDir, path, fileName);
                            upload = NfsUtil.upload(ip, nfsDir, path, fileName, imgBytes);
                        } catch (Exception e) {
                            e.printStackTrace();
                            throw new IOException(e);
                        }
                    }
                } catch (IOException e) {
                    log.error("更新图片失败,遥测数据----->{}", device);
                } catch (RuntimeException e) {
                    log.error("请求拉流服务异常,遥测数据----->{}", cameraId);
                }
            });
        }
    }

    @PostMapping("/http_url/test")
    public JSONObject getCameraImgByHttpUrlTest(@RequestBody JSONObject jsonObject) {
        JSONObject params = jsonObject.getJSONObject("params");
        String url = String.valueOf(params.get("url"));
        String deviceName = String.valueOf(params.get("deviceName"));
        log.info("查看截图的信息------>{},{}", url, deviceName);
        JSONObject result = new JSONObject();
        byte[] file = fileToBytes("E:\\bizhi\\4b2aa7bf90824d1c906a57a0bf4240a7.png");
        result.put("img1", Base64.getEncoder().encodeToString(file));
        result.put("img2", Base64.getEncoder().encodeToString(file));
        return result;
    }

    public static byte[] fileToBytes(String filePath) {
        byte[] buffer = null;
//        File file = new File(filePath);
        File file = FileUtils.getFile(filePath);
        FileInputStream fis = null;
        ByteArrayOutputStream bos = null;
        try {
            fis = new FileInputStream(file);
            bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            buffer = bos.toByteArray();
        } catch (FileNotFoundException ex) {
        } catch (IOException ex) {
        } finally {
            try {
                if (null != bos) {
                    bos.close();
                }
            } catch (IOException ex) {
            } finally {
                try {
                    if (null != fis) {
                        fis.close();
                    }
                } catch (IOException ex) {
                }
            }
        }
        return buffer;
    }

    @PostMapping("/updateImg_Device")
    public void updateImg(@RequestBody JSONObject jsonObject) {
        String device = String.valueOf(jsonObject.get("deviceName"));
        //获取处理中心的ip
        Map camerasAndId = tenantIpService.getCamerasIdByDeviceName(device);
        String ip = String.valueOf(camerasAndId.get("ip"));
        String cameraId = String.valueOf(camerasAndId.get("cameraid"));
        log.info("查询场地ip请求参数------->{},返回结果------->{}-----{}", device, ip, cameraId);
        //请求获取图片信息
        try {
            if (!(StringUtils.isEmpty(ip) || StringUtils.isEmpty(cameraId))) {
                String url = "http://" + ip + ":30005/cameraStream/getManualCapture?cameraId=" + cameraId;
                byte[] imgBytes = NfsUtil.getRequest(url);
//                        byte[] imgBytes = fileToBytes("E:\\bizhi\\4b2aa7bf90824d1c906a57a0bf4240a7.png");
                String path = "/thingsboard/default";
                // 使用 UUID 随机生成文件名
                String fileName = device + ".jpg";
                String nfsDir = "/data0/media";
                boolean upload = false;
                try {
                    log.info("ip----->{},nfsDir----->{},path------>{},fileName---->{}", ip, nfsDir, path, fileName);
                    upload = NfsUtil.upload(ip, nfsDir, path, fileName, imgBytes);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new IOException(e);
                }
            }
        } catch (IOException e) {
            log.error("更新图片失败,遥测数据----->{}", device);
        } catch (RuntimeException e) {
            log.error("请求拉流服务异常,遥测数据----->{}", cameraId);
        }
    }
}
